package com.huike.pmps.config.oauth;

import com.alibaba.fastjson.JSON;
import com.huike.pmps.model.vo.Result;
import com.huike.pmps.model.vo.StatusCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 〈资源认证服务器〉
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {


    @Bean
    @Primary
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
                Throwable cause = authException.getCause();
                response.setStatus(HttpStatus.OK.value());
                response.setHeader("Content-Type", "application/json;charset=UTF-8");
                try {
                    if (cause instanceof OAuth2AccessDeniedException) {
                        // 资源权限不足
                        response.getWriter().write(JSON.toJSONString(Result.failure(StatusCode.FAIL_403, "访问该资源权限不足")));
                    }
                    if ( cause instanceof InvalidTokenException) {
                        // 非法的token
                        response.getWriter().write(JSON.toJSONString(Result.failure(StatusCode.FAIL_401, "访问该资源的token无效")));
                    }
                    if(cause == null || cause instanceof InsufficientAuthenticationException){
                        response.getWriter().write(JSON.toJSONString(Result.failure(StatusCode.FAIL_401, "访问该资源需要进行认证，请先进行认证")));
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
    }

    @Autowired
    AuthenticationEntryPoint authenticationEntryPoint;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.authenticationEntryPoint(authenticationEntryPoint);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/oauth/**", "/api/file/**").permitAll()
                .antMatchers("/api/**").authenticated()
                .and().cors().and().csrf().disable().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)
                .and().httpBasic();
    }
}

